#ifndef METACPP_H__
#define METACPP_H__

template<
  bool cond,
  typename Then,
  typename Else
  >
class IF
{
public:
  typedef Then RET;
};
 
template<typename Then, typename Else>
class IF<false, Then, Else>
{
public:
  typedef Else RET;
};

template <typename U>
class ISVOID
{
public:
	enum{ RET=false	};
};

template<>
class ISVOID<void>
{
public:
	enum{ RET=true };
};



/*
template<typename U>
class ISREF
{
public:
  enum{ RET=false };
};

template<typename U>
class ISREF<U&>
{
public:
  enum{ RET=true };
};

*/

/*
template<typename U>
class NONCONST
{
public:
  typedef U RET;
  static void trace()
  { std::cout << "Default NONCONST<U>" << std::endl; }
};

template<typename U>
class NONCONST<const U>
{
public:
  typedef U RET;
  static void trace()
  { std::cout << "NONCONST<const U>" << std::endl; }
};

template<typename U>
class NONREF
{
public:
  typedef U RET;
  static void trace()
  { std::cout << "Default NONREF<U>" << std::endl; }
};

template<typename U>
class NONREF<U&>
{
public:
  typedef U RET;
  static void trace()
  { std::cout << "NONREF<U&>" << std::endl; }
};

template<typename Func>
class X
{
  typedef Func::first_argument_type first_arg;
  typedef NONCONST<NONREF<first_arg>::RET>::RET raw_first_arg;
public:
  X( const raw_first_arg & theFirstArg) : m_theFirstArg(theFirstArg)
  { 
    NONREF<first_arg>::trace();
    NONCONST<NONREF<first_arg>::RET>::trace();
    std::cout << std::endl;
  }
  
private:
  raw_first_arg m_theFirstArg;
};

class func1
{
  typedef int first_argument_type;
};

class func2
{
  typedef const int first_argument_type;
};

class func3
{
  typedef int& first_argument_type;
};

class func4
{
  typedef const int& first_argument_type;
};

int main()
{
  int arg = 42;
  X<func1> x1(arg);
  X<func2> x2(arg);
  X<func3> x3(arg);
  X<func4> x4(arg);
  return 0;
}
*/

#endif